Une intro…. Pas si petite
Pour suivre ce récapitulatif, veuillez installer les packages suivants:
Les packages du tidyverse: en tapant à la console install.packages("tidyverse").
Si vous ne les avez pas encore, les packages rmarkdown, knitr et devtools en tapant à la console install.packages(c("rmarkdown", "devtools")).
Pour ceux qui n’étaient pas là , vous avez raté quoi….
A la séance 3, on a eu une bonne dose d’installation qui a fait abandonné plusieurs personnes au cours de la séance parce que les amis n’avaient pas installé les packages nécessaires pour la séance. A la séance 4, on a essayé de rattraper le tir en montrant un peu le tidyverse, le ggplot2, les tests statistiques et une présentation sur la création de packages sous R. Malheureusement, on n’a pas pas pu faire les boucles et le if. On va y revenir dans le récapitulatif.
Outre la séance d’installation de la séance 3, on a introduit les projets de RStudio, le rmarkdown et on a effectué une petite introduction au tidyverse. On a ainsi appris à créer et gérer un projet sous Rstudio, traiter un document rmarkdown et on a lancé les bases du tidyverse avec un focus sur l’opérateur pipe… %>% Au passage on a appris quelques raccourcis claviers dont je vais reparler.
Quelques personnes s’étaient plaintes sur l’impossibilité de réaliser des documents lourds et structurés avec du rmarkdown. Je vais essayer de montrer que c’est faux et de vous faire prendre goût à rédiger vos documents et vos rapports dans la section sur rmarkdown, avec une introduction au bookdown. J’avais aussi promis de faire un clin d’œil sur le blogdown pour vous montrer rapidos comment créer votre propre blog ou site web, qui vous permettra si vous le nourrissez régulièrement de vous mettre à jour, d’apprendre aux autres et d’apprendre des autres aussi. J’ai aussi introduit une sous-section dessus dans la partie rmarkdown. Si c’est seulement cette section sur rmarkdown et compagnies qui vous intéresse, allez lire la section là.
Vous vous rappeler de notre base sur les essais randomisés? Après avoir introduit le tidyverse, on va essayer de vérifier que les classes d’age sont respectées en faisant une pyramide des âges (on l’a faite à la séance 4), et ensuite, on va passer à des tests statistiques pour vérifier quelques associations. Le tout sera accompagné de visualisations graphiques avec ggplot2. Si c’est juste la section sur ggplot2 et ses visualisations qui vous intéresse, je vous conseille de vous y plonger ici. Par contre, si vous ne vous intéressez qu’à la partie stats, n’hésitez pas à aller là.
A la fin de la séance, on a fait une petite demonstration sur la création de packages. Je vais revenir là dessus et vous montrer au passage les boucles et le if, avec quelques astuces. C’est la partie programmation et consorts… Si vous êtes là que pour ça, allez directement à la section concernée
Ça fait beaucoup de choses non? On y va!
Gestion d’un projet sous RStudio.
Structure du répertoire de travail
L’idee des projets est de mieux organiser votre travail - ou votre projet- sous R en gardant le repertoire de travail au repertoire du projet et en adopdant une hierarchie des dossiers qui va vous permettre de garder de bonnes habitudes de travail et de rigueur. La structure du dossier final de projet est la suivante :
dossier_projet
+
++++ dossier_projet.Rproj
+
++++++++ data/
+ +
+ ++++++++++ cas_pratique.dta
+ ++++++++++ cas_pratique.RData
+ ++++++++++ cas_pratique.sav
+ ++++++++++ cas_pratique.txt
+ ++++++++++ cas_pratique.xlsx
+
++++++++ input/
+
++++++++ output/
+ +++++++ figures/
+ +
+ +++++++ data/
+
++++++++ 1-premier-script.R
+
++++++++ 2-un-document-markdown.Rmd
+
++++++++ readme.txt
On commence par un dossier vide qui va etre le dossier de notre projet. Ce dossier sera de-facto le repertoire de travail lorsque l’on va lancer le projet sous Rstudio, ce qui permet d’eviter la partie set/get/wd.
Le dossier contient trois sous-dossiers :
Un dossier data dans lequel devraient se trouver les bases de donnees de notre analyse.
Un dossier input ou seront les figures et tout autre objets qui viendront enrichir notre travail, sans forcement provenir de R (captures d’ecran, etc.)
Un dossier output ou sera les sorties qui seront realisees avec R. Ces sorties sont divisees en deux principales parties: les figures et les graphes.
Creation du projet
On a d’abord creer notre projet en allant dans File > New Project.... On a obtenu la fenetre suivante et on a creer le projet dans un dossier. On a insiste sur le fait qu’un projet est en fait un dossier que Rstudio va creer. On a donc choisi l’option New Directory, puis l’option New Project et enfin un repertoire ou le dossier du projet va etre.

On a utilise les navigations dans l’onglet Files du quatrieme panneau (en bas a droite pour ceux qui n’on pas change la disposition par defaut) pour creer l’arborescence qu’on a presente en haut. On a alors introduit un fichier rmarkdown, qui devait contenir les codes et les output de nos travaux, et on l’a enregistre dans le dossier du projet. La prochaine section va en detail sur le rmarkdown et explique un peu comment il est concu.
Presentation et Gestion du rmarkdown
Historique
Comment est né R Markdown? De l’idée de faire du texte et du code R en même temps dans un même fichier, de façon reproductible et facilement partageable. Le pionnier de cette idée est Yihui Xie, qui s’est appuyé sur l’ancêtre du travail reproductible Sweave, qui permettait de faire du LaTeX et du R dans un même fichier, afin de faciliter la rédaction de rapports qui nécessitaient les mêmes types d’analyses. Il a lancé le package knitr sur lequel repose le package rmarkdown. C’est l’essentiel. R Markdown est souvent présenté sous la forme suivante, mettant en exergue les formats de sortie.

Pour ceux qui sont presses sur la syntaxe du markdown ou carrement n’ont pas envie de se taper la lecture de tout le tuto, je vous conseille de lire la feuille de triche faite par Rstudio. Vous pouvez ainsi sauter toute cette section pour aller lire celle sur le tidyverse et les tests statistiques.
Pourquoi utiliser R Markdown ?
“What is Reproducibility? Reproducibility is one of the main principles of the scientific method, and refers to the ability of a test or experiment to be accurately reproduced, or replicated, by someone else working independently.”
Yihui Xie
A cause des raisons suivantes:
La reproductibilite. L’idee de la reproductibilite est de permettre a tout un chacun de pouvoir reprendre sa propre etude et ses propres analyses, en suivant exactement les memes etapes que soit.
R Markdown a une syntaxe facile à maîtriser; en quelques minutes d’effort on acquiert l’essentiel pour écrire son document.
Avec un seul fichier, vous pouvez avoir plusieurs formats à la clé (Word, PDF (à condition d’avoir LaTeX), HTML)
Cela permet de faciliter le partage de fichiers, l’explication des scripts effectués et le partage au niveau de la communauté scientifique.
Et enfin, on peut écrire tout un article en Markdown. Faites un tour sur la Gallerie de rmarkdown et regardez la variété de documents que l’on peut réaliser avec.
Creation d’un fichier rmarkdown
On a appris a creer un fichier rmarkdown sous Rstudio. Pour ce faire, lancez R Markdown en effectuant les taches suivantes dans R Studio:
File>New File>R Markdown
Il apparaît alors une fenêtre demandant de préciser les paramètres du fichier que l’on a créé. Il faut preciser le titre du document, son auteur et le format de sortie. Il est possible d’avoir du word (en fait un .docx) ou du pdf comme format de sortie, je reviendrai dans la section sur la sortie pdf. Pour la version word, je vous renvoie a la documentation.

Une fois les paramètres spécifiés, on peut passer à l’analyse du document basique qui sert de début à l’apprentissage du langage de R Markdown. Il s’agit du document suivant:
L’en-tête d’un document R Markdown
L’en-tête d’un document R Markdown est constitué de petites phrases entourées d’un ---, comme dans le document utilisé pour créer ce fichier que vous lisez:
---
title: "Récapitulatif de la séance trois"
author: "Yves Amevoin, ISE"
date: "Novembre 2018"
output:
html_document:
css: style.css
highlight: kate
theme: yeti
toc: yes
toc_float: TRUE
dpi: 600
dev: "png"
code_download: TRUE
---
Cet ensemble de phrases contient les informations nécessaires au paramétrage du document. Le document lui même peut être considéré comme un ensemble de données (section, texte, code R), et les parties situées entre ces ---, des informations donnant des attributs et des paramètres à ces données (couleur, titre, date de création, format): On parle de métadonnées. Ces attributs doivent être transmis à un langage qui se charge de les stocker et de les rendre au document pour en changer l’aspect ou ajouter des informations. Ce langage, c’est le YAML qui signifiait au début Yet Another Markup Language mais qui est devenu YAML Aint Markup Language. En clair le YAML c’est quoi? Une syntaxe qui permet de stocker des données sur le document et qui les utilise pour paramétrer le document R Markdown et y ajouter des choses. Cette syntaxe est très stricte, avec des deux points, des retours à la ligne, des guillemets et des indentations (petits espaces après le retour à la ligne) pour cibler les sous-options d’une option mere. Par exemple, pour le html_document qui signifie le format de sortie, on a demande d’inclure une table des matieres (toc:yes), la possibilite de telecharger les codes du document (code_download : TRUE). Les options sont en general liees aux format de sortie liees au document que vous voulez obtenir. Comment les données sur le document sont stockées? Dans un objet appelé metadata dans le package rmarkdown. Regardez:
## [1] "Récapitulatif des séances trois et quatre"
Pour un document HTML, il existe une pléthore de paramètres (auteur, date, fonte, etc.) et l’on peut même ajouter un ficher qui prend bien en charge la mise en forme, comme mon fichier style.css que vous voyez dans l’option css. On peut en faire de même avec un fichier PDF. On pourrait écrire un article dessus. Mais en général le petit nombre de paramètres par défaut proposé par Rstudio suffit amplement pour des documents de petite envergure. Dans le cas où vous voulez des documents lourds, il serait souhaitable de jeter un coup d’œil sur les pages suivantes afin de regarder comment contrôler la mise en page:
Les chunks
Un fichier rmarkdown est un fichier dans lequel se trouvent les codes qui vont permettre de generer les analyses et les resultats associes aux analyses proprement dites ainsi que les commentaires de ces analyses. Ces codes se trouvent dans des portions grises appelees chunk, afin de les distinguer des commentaires - du texte brut - que vous ecrivez. Comment inserer un chunk lorsque l’on travaille sous Rstudio? Pour inserer un chunk R sous Rstudio, utilisez le raccourci clavier CTRL+ALT+I. Mais si vous voulez vous taper la syntaxe de l’ecriture, un chunk commence par ces trois accents graves ``` suivis de r que l’on met entre des accolades, ```{r} et il se termine par trois accents graves aussi ```. Une erreur commune est de ne pas terminer son chunk ou d’effacer par maladresse les trois accents de la fin.
Les chunk peuvent avoir des options en fonction de comment l’on veut traiter le rendu. En general on peut soit vouloir afficher le code ou pas, soit la sortie du code ou pas, soit evaluer le code ou pas. Vous pouvez parcourir les options d’un chunk R que vous aurez insere en cliquant sur les parametres du chunk.
Une fois que vous verrez comment les options ont ete inserees, vous pouvez taper le code vous meme. On a donc recharge notre base de donnees en utilisant le chunk suivant:
Les chunks par defaut, supposent que vous avez du R comme langage, mais il est possible de creer des chuncks avec d’autres langages. Vous pouvez choisir le langage associe au chunk que vous voulez inserer en cliquant sur insert en haut a gauche de l’editeur. En bas par exemple, j’insere un chunk avec des commandes systemes.
## fom_my_key
## Mega
## personal_folder
## personal_learnings
## personal_projects
## ressources
## software
## test_projets
## work_for_others
Si vous faites de meme, vous verrez que votre chunk commence par ```{bash}. Cela permet a knitr de savoir quel langage utilise dans le chunk.
Les chunk peuvent avoir un nom. L’idee est de leur permettre d’etre facilement accessible en utilisant les onglets de navigation de Rstudio. Pour nommer un chunk, il suffit de mettre
Le chunk setup
Insérer des Images, Insérer des tableaux
Le fichier que vous lisez est plein d’images qui permettent d’illustrer les propos. On peut insérer des images dans un fichier R Markdown. Pour cela il faut donner un identifiant à l’image (comme par exemple monimage) et l’insérer dans le document de la façon suivante:
![Le titre de l'image][monimage]
Mais comment R Markdown retrouve l’image correspondante? En mettant à la fin du fichier les références permettant d’atteindre l’image. La syntaxe est la suivante pour un format png par exemple.
[monimage]: Chemin_vers_limage/image.png "Texte popup qui s'affiche quand la souris survole"
L’identifiant peut être utilisé pour indexer l’image à travers un lien dans le document, comme j’ai fait pour ici
Les Tableaux
Il existe plusieurs manières d’insérer un tableau, la façon la plus recommandée étant d’utiliser le package knitr comme présenté précédemment. Cependant, il est possible d’insérer un tableau dans un document R Markdown de la façon suivante, ou les deux points permettent de dire comment l’on veut aligner les elements du tableau.
: Un Tableau
|Aligné à Droite|Aligné à Gauche|Par Défaut|Au Centre|
|--------------:|:--------------|----------|:-------:|
|Installez |N'oubliez pas |Package | les |
|les |Dinstaller |Installez |package |
|package |les |avant de venir|5 |
Un Tableau
|
Installez
|
N’oubliez pas
|
Package
|
les
|
|
les
|
Dinstaller
|
Installez
|
package
|
|
package
|
les
|
avant de venir
|
5
|
Les petits plus pour finir
Et pour un document lourd? Ou un article?
N’exagérons rien, me direz-vous…. Pourquoi rédiger un livre entier ou un article dans Rstudio alors qu’on a Word?
Parce que c’est reproductible
Vous vous rendez-compte d’une erreur? Une modification et ça y est! tout est réglé. Pas de copier coller avec des pertes de temps et des risques d’erreurs. Aussi, vous pouvez juste balancer le code à un ami et il peut reprendre les mêmes analyses et observer si vous avez tout bien fait, ou loupez quelque chose… Ça n’arrange que la recherche.
Revenons au titre, comment rédiger un article sous R Markdown. Lorsque vous décidez de créer un nouveau document sous R Markdown, vous avez une page suivante correspondant au document que vous voulez:
[][Template]
En bas, vous pouvez choisir l’option From Template pour créer le document à partir d’exemplaires existant déjà. Cette section nous permet de choisir un ensemble d’exemplaires et de les utiliser à outrance lorsque vous souhaitez faire un nouveau document R Markdown, en passant outre le format basique que Rstudio propose.
Qu’est ce qu’un Template de R markdown?
C’est un ensemble de formats et de propriétés prédéfinis qui vous permettent d’accélérer le travail si vous avez l’habitude d’écrire des documents qui ont la même structure. On peut en créer un avec R Markdown, mais cela nécessite un peu de tweak…
Vous pouvez néanmoins utiliser des Template existants, en installant le package rticles par exemple qui vous permettra d’avoir les formats prédéfinis pour les articles dans différents journaux. Si vous pensez publier dans tel ou tel journal, vous pouvez définir un Template pour ce journal s’il n’existe pas et rédiger avec, ou même le partager. Installez le package rticles,
Puis vous verrez les exemplaires pour les articles dans la section From Template. Pour le reste, à vous de jouer. Vous pouvez ajouter d’autres Templates en faisant un tour sur la gallerie de R Markdown.
LS0tCnRpdGxlOiAiUsOpY2FwaXR1bGF0aWYgZGVzIHPDqWFuY2VzIHRyb2lzIGV0IHF1YXRyZSIKYXV0aG9yOiAiWXZlcyBBbWV2b2luLCBJU0UiCmRhdGU6ICJEw6ljZW1icmUgMjAxOCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjc3M6IHN0eWxlLmNzcwogICAgaGlnaGxpZ2h0OiBrYXRlCiAgICB0aGVtZTogeWV0aQogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogVFJVRQogICAgZHBpOiAxODAwCiAgICBkZXY6ICJwbmciCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCi0tLQoKIyMgVW5lIGludHJvLi4uLiBQYXMgc2kgcGV0aXRlCgpQb3VyIHN1aXZyZSBjZSByw6ljYXBpdHVsYXRpZiwgdmV1aWxsZXogaW5zdGFsbGVyIGxlcyBwYWNrYWdlcyBzdWl2YW50czoKCi0gTGVzIHBhY2thZ2VzIGR1IGB0aWR5dmVyc2VgOiBlbiB0YXBhbnQgw6AgbGEgY29uc29sZSAKYGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpYC4KCi0gU2kgdm91cyBuZSBsZXMgYXZleiBwYXMgZW5jb3JlLCBsZXMgcGFja2FnZXMgYHJtYXJrZG93bmAsIGBrbml0cmAgZXQgYGRldnRvb2xzYCBlbiB0YXBhbnQgw6AgbGEgCmNvbnNvbGUgYGluc3RhbGwucGFja2FnZXMoYygicm1hcmtkb3duIiwgImRldnRvb2xzIikpYC4KCi0tLQoKYGBge2Jsb2NrIGludHJvLCB0eXBlID0gIm1vbnR5cGUyIn0KCiMjIyMgUG91ciBjZXV4IHF1aSBu4oCZw6l0YWllbnQgcGFzIGzDoCAsIHZvdXMgYXZleiByYXTDqSBxdW9pLi4uLgoKQSBsYSBzw6lhbmNlIDMsIG9uIGEgZXUgdW5lIGJvbm5lIGRvc2UgZCdpbnN0YWxsYXRpb24gcXVpIGEgZmFpdCBhYmFuZG9ubsOpIApwbHVzaWV1cnMgcGVyc29ubmVzIGF1IGNvdXJzIGRlIGxhIHPDqWFuY2UgcGFyY2UgcXVlIGxlcyBhbWlzIG4nYXZhaWVudCBwYXMgCmluc3RhbGzDqSBsZXMgcGFja2FnZXMgbsOpY2Vzc2FpcmVzIHBvdXIgbGEgc8OpYW5jZS4gQSBsYSBzw6lhbmNlIDQsIG9uIGEgZXNzYXnDqQpkZSByYXR0cmFwZXIgbGUgdGlyIGVuIG1vbnRyYW50IHVuIHBldSBsZSBgdGlkeXZlcnNlYCwgbGUgZ2dwbG90MiwgbGVzIHRlc3RzCnN0YXRpc3RpcXVlcyBldCB1bmUgcHLDqXNlbnRhdGlvbiBzdXIgIGxhIGNyw6lhdGlvbiBkZSBwYWNrYWdlcyBzb3VzIFIuIApNYWxoZXVyZXVzZW1lbnQsIG9uIG4nYSBwYXMgcGFzIHB1IGZhaXJlIGxlcyBib3VjbGVzIGV0IGxlIGlmLiAKT24gdmEgeSByZXZlbmlyIGRhbnMgbGUgcsOpY2FwaXR1bGF0aWYuCgpPdXRyZSBsYSBzw6lhbmNlIGQnaW5zdGFsbGF0aW9uIGRlIGxhIHPDqWFuY2UgMywgb24gYSBpbnRyb2R1aXQgbGVzIHByb2pldHMgZGUgCipSU3R1ZGlvKiwgbGUgYHJtYXJrZG93bmAgZXQgb24gYSBlZmZlY3R1w6kgdW5lIHBldGl0ZSBpbnRyb2R1Y3Rpb24gYXUgYHRpZHl2ZXJzZWAuIApPbiBhIGFpbnNpIGFwcHJpcyDDoCBjcsOpZXIgZXQgZ8OpcmVyIHVuIHByb2pldCBzb3VzICpSc3R1ZGlvKiwgdHJhaXRlciB1biBkb2N1bWVudApgcm1hcmtkb3duYCBldCBvbiBhIGxhbmPDqSBsZXMgYmFzZXMgZHUgYHRpZHl2ZXJzZWAgYXZlYyB1biBmb2N1cyBzdXIgbOKAmW9ww6lyYXRldXIKcGlwZS4uLiAlPiUgQXUgcGFzc2FnZSBvbiBhIGFwcHJpcyBxdWVscXVlcyByYWNjb3VyY2lzIGNsYXZpZXJzIApkb250IGplIHZhaXMgcmVwYXJsZXIuIAoKUXVlbHF1ZXMgcGVyc29ubmVzIHMnw6l0YWllbnQgcGxhaW50ZXMgc3VyIGwnaW1wb3NzaWJpbGl0w6kgZGUgcsOpYWxpc2VyIGRlcyAKZG9jdW1lbnRzIGxvdXJkcyBldCBzdHJ1Y3R1csOpcyBhdmVjIGR1IGBybWFya2Rvd25gLiBKZSB2YWlzIGVzc2F5ZXIgZGUgbW9udHJlciAKcXVlIGMnZXN0IGZhdXggZXQgZGUgdm91cyBmYWlyZSBwcmVuZHJlIGdvw7t0IMOgIHLDqWRpZ2VyIHZvcyBkb2N1bWVudHMgZXQgdm9zIApyYXBwb3J0cyBkYW5zIGxhIHNlY3Rpb24gc3VyIGBybWFya2Rvd25gLCBhdmVjIHVuZSBpbnRyb2R1Y3Rpb24gYXUgYGJvb2tkb3duYC4gCkonYXZhaXMgYXVzc2kgcHJvbWlzIGRlIGZhaXJlIHVuIGNsaW4gZOKAmcWTaWwgc3VyIGxlIGBibG9nZG93bmAgcG91ciB2b3VzIG1vbnRyZXIgCnJhcGlkb3MgY29tbWVudCBjcsOpZXIgdm90cmUgcHJvcHJlIGJsb2cgb3Ugc2l0ZSB3ZWIsIHF1aSB2b3VzIHBlcm1ldHRyYSBzaSB2b3VzIGxlCm5vdXJyaXNzZXogcsOpZ3VsacOocmVtZW50IGRlIHZvdXMgbWV0dHJlIMOgIGpvdXIsIGQnYXBwcmVuZHJlIGF1eCBhdXRyZXMgZXQgCmQnYXBwcmVuZHJlIGRlcyBhdXRyZXMgYXVzc2kuIEonYWkgYXVzc2kgaW50cm9kdWl0IHVuZSBzb3VzLXNlY3Rpb24gZGVzc3VzIApkYW5zIGxhIHBhcnRpZSBgcm1hcmtkb3duYC4gU2kgYydlc3Qgc2V1bGVtZW50IGNldHRlIHNlY3Rpb24gc3VyIGBybWFya2Rvd25gIGV0CmNvbXBhZ25pZXMgcXVpIHZvdXMgaW50w6lyZXNzZSwgYWxsZXogbGlyZSBsYSBbc2VjdGlvbiBsw6BdKCNsaWVudmVyc2xhc2VjdGlvbnJtZCkuCgpWb3VzIHZvdXMgcmFwcGVsZXIgZGUgbm90cmUgYmFzZSBzdXIgbGVzIGVzc2FpcyByYW5kb21pc8Opcz8gQXByw6hzIGF2b2lyIAppbnRyb2R1aXQgbGUgYHRpZHl2ZXJzZWAsIG9uIHZhIGVzc2F5ZXIgZGUgdsOpcmlmaWVyIHF1ZSBsZXMgY2xhc3NlcyBkJ2FnZSBzb250IApyZXNwZWN0w6llcyBlbiBmYWlzYW50IHVuZSBweXJhbWlkZSBkZXMgw6JnZXMgKG9uIGwnYSBmYWl0ZSDDoCBsYSBzw6lhbmNlIDQpLApldCBlbnN1aXRlLCBvbiB2YSBwYXNzZXIgw6AgZGVzIHRlc3RzIHN0YXRpc3RpcXVlcyBwb3VyIHbDqXJpZmllciBxdWVscXVlcyAKYXNzb2NpYXRpb25zLiBMZSB0b3V0IHNlcmEgYWNjb21wYWduw6kgZGUgdmlzdWFsaXNhdGlvbnMgZ3JhcGhpcXVlcyBhdmVjIGBnZ3Bsb3QyYC4KU2kgYydlc3QganVzdGUgbGEgc2VjdGlvbiBzdXIgYGdncGxvdDJgIGV0IHNlcyB2aXN1YWxpc2F0aW9ucyBxdWkgdm91cyBpbnTDqXJlc3NlLCAKamUgdm91cyBjb25zZWlsbGUgZGUgdm91cyB5IFtwbG9uZ2VyIGljaV0oI2xpZW52ZXJzbGFzZWN0aW9uZ2dwbG90MikuIFBhciBjb250cmUsIApzaSB2b3VzIG5lIHZvdXMgaW50w6lyZXNzZXogcXUnw6AgbGEgcGFydGllIHN0YXRzLCAKW24naMOpc2l0ZXogcGFzIMOgIGFsbGVyIGzDoF0oI2xpZW52ZXJzbGVzc3RhdHMpLgoKQSBsYSBmaW4gZGUgbGEgc8OpYW5jZSwgb24gYSBmYWl0IHVuZSBwZXRpdGUgZGVtb25zdHJhdGlvbiBzdXIgbGEgY3LDqWF0aW9uIGRlIHBhY2thZ2VzLiAKSmUgdmFpcyByZXZlbmlyIGzDoCBkZXNzdXMgZXQgdm91cyBtb250cmVyIGF1IHBhc3NhZ2UgbGVzIGJvdWNsZXMgZXQgbGUgaWYsIGF2ZWMgCnF1ZWxxdWVzIGFzdHVjZXMuIEMnZXN0IGxhIHBhcnRpZSBwcm9ncmFtbWF0aW9uIGV0IGNvbnNvcnRzLi4uIFNpIHZvdXMgw6p0ZXMgbMOgIHF1ZSBwb3VyIMOnYSwKYWxsZXogZGlyZWN0ZW1lbnQgw6AgW2xhIHNlY3Rpb24gY29uY2VybsOpZV0oI2xpZW52ZXJzbGFzZWN0aW9ucGFja2FnZSkKCsOHYSBmYWl0IGJlYXVjb3VwIGRlIGNob3NlcyBub24/IE9uIHkgdmEhIFteN10KYGBgCgoKIyMgR2VzdGlvbiBkJ3VuIHByb2pldCBzb3VzICpSU3R1ZGlvKi4KCiMjIyBTdHJ1Y3R1cmUgZHUgcsOpcGVydG9pcmUgZGUgdHJhdmFpbAoKTCdpZGVlIGRlcyBwcm9qZXRzIGVzdCBkZSBtaWV1eCBvcmdhbmlzZXIgdm90cmUgdHJhdmFpbCAtIG91IHZvdHJlIHByb2pldC0gc291cyBSIGVuIGdhcmRhbnQgbGUgcmVwZXJ0b2lyZQpkZSB0cmF2YWlsIGF1IHJlcGVydG9pcmUgZHUgcHJvamV0IGV0IGVuIGFkb3BkYW50IHVuZSBoaWVyYXJjaGllIGRlcyBkb3NzaWVycyBxdWkgdmEgdm91cyBwZXJtZXR0cmUgZGUgZ2FyZGVyCmRlIGJvbm5lcyBoYWJpdHVkZXMgZGUgdHJhdmFpbCBldCBkZSByaWd1ZXVyLiBMYSBzdHJ1Y3R1cmUgZHUgZG9zc2llciBmaW5hbCBkZSBwcm9qZXQgZXN0IGxhIHN1aXZhbnRlIFteMV06CgogICAgICAgICAgZG9zc2llcl9wcm9qZXQKICAgICAgICAgICAgKwogICAgICAgICAgICArKysrIGRvc3NpZXJfcHJvamV0LlJwcm9qCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgZGF0YS8KICAgICAgICAgICAgKyAgICAgICAgICsKICAgICAgICAgICAgKyAgICAgICAgICsrKysrKysrKysgY2FzX3ByYXRpcXVlLmR0YQogICAgICAgICAgICArICAgICAgICAgKysrKysrKysrKyBjYXNfcHJhdGlxdWUuUkRhdGEKICAgICAgICAgICAgKyAgICAgICAgICsrKysrKysrKysgY2FzX3ByYXRpcXVlLnNhdgogICAgICAgICAgICArICAgICAgICAgKysrKysrKysrKyBjYXNfcHJhdGlxdWUudHh0CiAgICAgICAgICAgICsgICAgICAgICArKysrKysrKysrIGNhc19wcmF0aXF1ZS54bHN4CiAgICAgICAgICAgICsgICAgICAgICAKICAgICAgICAgICAgKysrKysrKysgaW5wdXQvCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgb3V0cHV0LwogICAgICAgICAgICArICAgICAgICAgICArKysrKysrIGZpZ3VyZXMvCiAgICAgICAgICAgICsgICAgICAgICAgICsKICAgICAgICAgICAgKyAgICAgICAgICAgKysrKysrKyBkYXRhLwogICAgICAgICAgICArCiAgICAgICAgICAgICsrKysrKysrIDEtcHJlbWllci1zY3JpcHQuUgogICAgICAgICAgICArCiAgICAgICAgICAgICsrKysrKysrIDItdW4tZG9jdW1lbnQtbWFya2Rvd24uUm1kCiAgICAgICAgICAgICsKICAgICAgICAgICAgKysrKysrKysgcmVhZG1lLnR4dAogICAgICAgICAgICAKCk9uIGNvbW1lbmNlIHBhciB1biBkb3NzaWVyIHZpZGUgcXVpIHZhIGV0cmUgbGUgZG9zc2llciBkZSBub3RyZSBwcm9qZXQuIENlIGRvc3NpZXIgc2VyYSBkZS1mYWN0byBsZQpyZXBlcnRvaXJlIGRlIHRyYXZhaWwgbG9yc3F1ZSBsJ29uIHZhIGxhbmNlciBsZSBwcm9qZXQgc291cyAqUnN0dWRpbyosIGNlIHF1aSBwZXJtZXQgZCdldml0ZXIKbGEgcGFydGllIGBzZXQvZ2V0L3dkYC4KCkxlIGRvc3NpZXIgY29udGllbnQgdHJvaXMgc291cy1kb3NzaWVycyBbXjJdOgoKLSBVbiBkb3NzaWVyIGBkYXRhYCBkYW5zIGxlcXVlbCBkZXZyYWllbnQgc2UgdHJvdXZlciBsZXMgYmFzZXMgZGUgZG9ubmVlcyBkZSBub3RyZSBhbmFseXNlLgoKLSBVbiBkb3NzaWVyIGBpbnB1dGAgb3Ugc2Vyb250IGxlcyBmaWd1cmVzIGV0IHRvdXQgYXV0cmUgb2JqZXRzIHF1aSB2aWVuZHJvbnQgZW5yaWNoaXIgbm90cmUgdHJhdmFpbCwKc2FucyBmb3JjZW1lbnQgcHJvdmVuaXIgZGUgUiAoY2FwdHVyZXMgZCdlY3JhbiwgZXRjLikKCi0gVW4gZG9zc2llciBgb3V0cHV0YCBvdSBzZXJhIGxlcyBzb3J0aWVzIHF1aSBzZXJvbnQgcmVhbGlzZWVzIGF2ZWMgYFJgLiBDZXMgc29ydGllcyBzb250IGRpdmlzZWVzCmVuIGRldXggcHJpbmNpcGFsZXMgcGFydGllczogbGVzIGZpZ3VyZXMgZXQgbGVzIGdyYXBoZXMuCgojIyMgQ3JlYXRpb24gZHUgcHJvamV0CgpPbiBhIGQnYWJvcmQgY3JlZXIgbm90cmUgcHJvamV0IGVuIGFsbGFudCBkYW5zIGBGaWxlID4gIE5ldyBQcm9qZWN0Li4uYC4gT24gYSBvYnRlbnUgbGEgZmVuZXRyZSBzdWl2YW50ZSBldCBvbiBhIGNyZWVyIGxlIHByb2pldCBkYW5zIHVuIGRvc3NpZXIuIE9uIGEgaW5zaXN0ZSBzdXIgbGUgZmFpdCBxdSd1biBwcm9qZXQKZXN0IGVuIGZhaXQgdW4gZG9zc2llciBxdWUgKlJzdHVkaW8qIHZhIGNyZWVyLgpPbiBhIGRvbmMgY2hvaXNpIGwnb3B0aW9uIGBOZXcgRGlyZWN0b3J5YCwgcHVpcyBsJ29wdGlvbiBgTmV3IFByb2plY3RgIGV0IGVuZmluIHVuIHJlcGVydG9pcmUKb3UgbGUgZG9zc2llciBkdSBwcm9qZXQgdmEgZXRyZS4KCmBgYHtyIGZpZ3VyZS1wcm9qZXQsIGVjaG89RkFMU0UsIG91dC53aWR0aCA9ICc0MDAlJ30Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoImZpZ3VyZXMvcHJvamVjdF9jcmVhdGlvbi5wbmciKQoKYGBgCgoKCk9uIGEgdXRpbGlzZSBsZXMgbmF2aWdhdGlvbnMgZGFucyBsJ29uZ2xldCBgRmlsZXNgIGR1IHF1YXRyaWVtZSBwYW5uZWF1IChlbiBiYXMgYSBkcm9pdGUgcG91ciBjZXV4IHF1aSBuJ29uIHBhcyBjaGFuZ2UgbGEgZGlzcG9zaXRpb24gcGFyIGRlZmF1dCkgcG91ciBjcmVlciBsJ2FyYm9yZXNjZW5jZSBxdSdvbiBhIHByZXNlbnRlIGVuIGhhdXQuCk9uIGEgYWxvcnMgaW50cm9kdWl0IHVuIGZpY2hpZXIgcm1hcmtkb3duLCBxdWkgZGV2YWl0IGNvbnRlbmlyIGxlcyBjb2RlcyBldCBsZXMgb3V0cHV0IGRlIG5vcyB0cmF2YXV4LCBldCBvbiBsJ2EgZW5yZWdpc3RyZSBkYW5zIGxlIGRvc3NpZXIgZHUgcHJvamV0LiBMYSBwcm9jaGFpbmUgc2VjdGlvbiB2YSBlbiBkZXRhaWwgc3VyIGxlIHJtYXJrZG93biBldCBleHBsaXF1ZSB1biBwZXUgY29tbWVudCBpbCBlc3QgY29uY3UuCgoKCiMjIFByZXNlbnRhdGlvbiBldCBHZXN0aW9uIGR1IHJtYXJrZG93bgoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25ybWQiLz4KPC9hPgoKCiMjIyBIaXN0b3JpcXVlCgpDb21tZW50IGVzdCBuw6kgUiBNYXJrZG93bj8gW14zXSBEZSBsJ2lkw6llIGRlIGZhaXJlIGR1IHRleHRlIGV0IGR1IGNvZGUgUiBlbiBtw6ptZSB0ZW1wcyBkYW5zIHVuIG3Dqm1lIGZpY2hpZXIsIGRlIGZhw6dvbiByZXByb2R1Y3RpYmxlIGV0IGZhY2lsZW1lbnQgcGFydGFnZWFibGUuIExlIHBpb25uaWVyIGRlIGNldHRlIGlkw6llIGVzdCBZaWh1aSBYaWUsIHF1aSBzJ2VzdCBhcHB1ecOpIHN1ciBsJ2FuY8OqdHJlIGR1IHRyYXZhaWwgcmVwcm9kdWN0aWJsZSBgU3dlYXZlYCwgcXVpIHBlcm1ldHRhaXQgZGUgZmFpcmUgZHUgTGFUZVggZXQgZHUgUiBkYW5zIHVuIG3Dqm1lIGZpY2hpZXIsIGFmaW4gZGUgZmFjaWxpdGVyIGxhIHLDqWRhY3Rpb24gZGUgcmFwcG9ydHMgcXVpIG7DqWNlc3NpdGFpZW50IGxlcyBtw6ptZXMgdHlwZXMgZCdhbmFseXNlcy4gSWwgYSBsYW5jw6kgbGUgcGFja2FnZSBba25pdHJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9rbml0ci9pbmRleC5odG1sKSBzdXIgbGVxdWVsIHJlcG9zZSBsZSBwYWNrYWdlICpybWFya2Rvd24qLiBDJ2VzdCBsJ2Vzc2VudGllbC4gUiBNYXJrZG93biBlc3Qgc291dmVudCBwcsOpc2VudMOpIHNvdXMgbGEgZm9ybWUgc3VpdmFudGUsIG1ldHRhbnQgZW4gZXhlcmd1ZSBsZXMgZm9ybWF0cyBkZSBzb3J0aWUuCgohW11bT3V0cHV0Rm9ybWF0XQoKClBvdXIgY2V1eCBxdWkgc29udCBwcmVzc2VzIHN1ciBsYSBzeW50YXhlIGR1IG1hcmtkb3duIG91IGNhcnJlbWVudCB+fm4nb250IHBhcyBlbnZpZSBkZSBzZSB0YXBlcn5+IGxhIGxlY3R1cmUgZGUgdG91dCBsZSB0dXRvLApqZSB2b3VzIGNvbnNlaWxsZSBkZSBsaXJlIGxhIFtmZXVpbGxlIGRlIHRyaWNoZV0oaHR0cHM6Ly93d3cucnN0dWRpby5vcmcvbGlua3Mvcl9tYXJrZG93bl9jaGVhdF9zaGVldCkKZmFpdGUgcGFyICpSc3R1ZGlvKi4gVm91cyBwb3V2ZXogYWluc2kgc2F1dGVyIHRvdXRlIGNldHRlIHNlY3Rpb24gcG91ciBhbGxlciBsaXJlIGNlbGxlIHN1ciBsZSB0aWR5dmVyc2UgZXQgbGVzIHRlc3RzIHN0YXRpc3RpcXVlcy4KCgojIyMgUG91cnF1b2kgdXRpbGlzZXIgUiBNYXJrZG93biA/CgpgYGB7YmxvY2sgcXVvdGUtcmVwcm9kdWN0aWJpbGl0eSwgdHlwZSA9ICJtb250eXBlMiJ9CgoiV2hhdCBpcyBSZXByb2R1Y2liaWxpdHk/CiBSZXByb2R1Y2liaWxpdHkgaXMgb25lIG9mIHRoZSBtYWluIHByaW5jaXBsZXMgb2YgdGhlIHNjaWVudGlmaWMgbWV0aG9kLCBhbmQgcmVmZXJzIHRvIHRoZSBhYmlsaXR5IG9mIGEgdGVzdCBvciBleHBlcmltZW50IHRvIGJlIGFjY3VyYXRlbHkgcmVwcm9kdWNlZCwgb3IgcmVwbGljYXRlZCwgYnkgc29tZW9uZSBlbHNlIHdvcmtpbmcgaW5kZXBlbmRlbnRseS4iCiAKICoqWWlodWkgWGllKioKCmBgYAoKCkEgY2F1c2UgZGVzIHJhaXNvbnMgc3VpdmFudGVzOgoKMS4gTGEgcmVwcm9kdWN0aWJpbGl0ZS4gTCdpZGVlIGRlIGxhIHJlcHJvZHVjdGliaWxpdGUgZXN0IGRlIHBlcm1ldHRyZSBhIHRvdXQgdW4KY2hhY3VuIGRlIHBvdXZvaXIgcmVwcmVuZHJlIHNhIHByb3ByZSBldHVkZSBldCBzZXMgcHJvcHJlcyBhbmFseXNlcywgZW4gc3VpdmFudApleGFjdGVtZW50IGxlcyBtZW1lcyBldGFwZXMgcXVlIHNvaXQuCgoKMS4gUiBNYXJrZG93biBhIHVuZSBzeW50YXhlIGZhY2lsZSDDoCBtYcOudHJpc2VyOyBlbiBxdWVscXVlcyBtaW51dGVzIGQnZWZmb3J0IG9uIGFjcXVpZXJ0IGwnZXNzZW50aWVsIHBvdXIgw6ljcmlyZSBzb24gZG9jdW1lbnQuCgoyLiBBdmVjIHVuIHNldWwgZmljaGllciwgdm91cyBwb3V2ZXogYXZvaXIgcGx1c2lldXJzIGZvcm1hdHMgw6AgbGEgY2zDqSAoV29yZCwgUERGICjDoCBjb25kaXRpb24gZCdhdm9pciBMYVRlWCksIEhUTUwpCgoKMy4gQ2VsYSBwZXJtZXQgZGUgZmFjaWxpdGVyIGxlIHBhcnRhZ2UgZGUgZmljaGllcnMsIGwnZXhwbGljYXRpb24gZGVzIHNjcmlwdHMgZWZmZWN0dcOpcyBldCBsZSBwYXJ0YWdlIGF1IG5pdmVhdSBkZSBsYSBjb21tdW5hdXTDqSBzY2llbnRpZmlxdWUuCgpFdCBlbmZpbiwgb24gcGV1dCDDqWNyaXJlIHRvdXQgdW4gYXJ0aWNsZSBlbiBNYXJrZG93bi4KRmFpdGVzIHVuIHRvdXIgc3VyIFtsYSBHYWxsZXJpZSBkZSBybWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vZ2FsbGVyeS5odG1sKSBldCByZWdhcmRleiBsYSB2YXJpw6l0w6kgZGUgZG9jdW1lbnRzIHF1ZSBsJ29uIHBldXQgcsOpYWxpc2VyIGF2ZWMuCgoKIyMjIENyZWF0aW9uIGQndW4gZmljaGllciBybWFya2Rvd24KCk9uIGEgYXBwcmlzIGEgY3JlZXIgdW4gZmljaGllciBybWFya2Rvd24gc291cyAqUnN0dWRpbyouIFBvdXIgY2UgZmFpcmUsIGxhbmNleiBSIE1hcmtkb3duIGVuIGVmZmVjdHVhbnQgbGVzIHRhY2hlcyBzdWl2YW50ZXMgZGFucyBSIFN0dWRpbzoKCmBGaWxlPk5ldyBGaWxlPlIgTWFya2Rvd25gCgpJbCBhcHBhcmHDrnQgYWxvcnMgdW5lIGZlbsOqdHJlIGRlbWFuZGFudCBkZSBwcsOpY2lzZXIgbGVzIHBhcmFtw6h0cmVzIGR1IGZpY2hpZXIgcXVlIGwnb24gYSBjcsOpw6kuIElsIGZhdXQgcHJlY2lzZXIgbGUgdGl0cmUgZHUgZG9jdW1lbnQsIHNvbiBhdXRldXIgZXQgbGUgZm9ybWF0IGRlIHNvcnRpZS4gSWwgZXN0IHBvc3NpYmxlIGQnYXZvaXIgZHUgYHdvcmRgIChlbiBmYWl0IHVuIGAuZG9jeGApIG91IGR1IGBwZGZgIGNvbW1lIGZvcm1hdCBkZSBzb3J0aWUsIGplIHJldmllbmRyYWkgZGFucyBsYSBzZWN0aW9uIHN1ciBsYSBzb3J0aWUgYHBkZmAuIFBvdXIgbGEgdmVyc2lvbiB3b3JkLCBqZSB2b3VzIHJlbnZvaWUgYSBbbGEgZG9jdW1lbnRhdGlvbl0oKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20vd29yZF9kb2N1bWVudF9mb3JtYXQuaHRtbCkpW142XS4gCgoKIVtdW1BhcmFtZXRyZV0KCgpVbmUgZm9pcyBsZXMgcGFyYW3DqHRyZXMgc3DDqWNpZmnDqXMsIG9uIHBldXQgcGFzc2VyIMOgIGwnYW5hbHlzZSBkdSBkb2N1bWVudCBiYXNpcXVlIHF1aSBzZXJ0IGRlIGTDqWJ1dCDDoCBsJ2FwcHJlbnRpc3NhZ2UgZHUgbGFuZ2FnZSBkZSBSIE1hcmtkb3duLiBJbCBzJ2FnaXQgZHUgZG9jdW1lbnQgc3VpdmFudDoKCjxjZW50ZXI+CiFbXVtGaWNoaWVyQmFzaXF1ZV0KPC9jZW50ZXI+CgojIyMgTCdlbi10w6p0ZSBkJ3VuIGRvY3VtZW50IFIgTWFya2Rvd24KCkwnZW4tdMOqdGUgZCd1biBkb2N1bWVudCBSIE1hcmtkb3duIGVzdCBjb25zdGl0dcOpIGRlIHBldGl0ZXMgcGhyYXNlcyBlbnRvdXLDqWVzIGQndW4gYC0tLWAsIGNvbW1lIGRhbnMgbGUgZG9jdW1lbnQgdXRpbGlzw6kgcG91ciBjcsOpZXIgY2UgZmljaGllciBxdWUgdm91cyBsaXNlejoKCmBgYAotLS0KdGl0bGU6ICJSw6ljYXBpdHVsYXRpZiBkZSBsYSBzw6lhbmNlIHRyb2lzIgphdXRob3I6ICJZdmVzIEFtZXZvaW4sIElTRSIKZGF0ZTogIk5vdmVtYnJlIDIwMTgiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY3NzOiBzdHlsZS5jc3MKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgdGhlbWU6IHlldGkKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIGRwaTogNjAwCiAgICBkZXY6ICJwbmciCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFCi0tLQpgYGAKCgpDZXQgZW5zZW1ibGUgZGUgcGhyYXNlcyAgY29udGllbnQgbGVzIGluZm9ybWF0aW9ucyBuw6ljZXNzYWlyZXMgYXUgcGFyYW3DqXRyYWdlIGR1IGRvY3VtZW50LiBMZSBkb2N1bWVudCBsdWkgbcOqbWUgcGV1dCDDqnRyZSBjb25zaWTDqXLDqSBjb21tZSB1biBlbnNlbWJsZSBkZSBkb25uw6llcyAoc2VjdGlvbiwgdGV4dGUsIGNvZGUgUiksIGV0IGxlcyBwYXJ0aWVzIHNpdHXDqWVzIGVudHJlIGNlcyBgLS0tYCwgZGVzIGluZm9ybWF0aW9ucyBkb25uYW50IGRlcyBhdHRyaWJ1dHMgZXQgZGVzIHBhcmFtw6h0cmVzIMOgIGNlcyBkb25uw6llcyAoY291bGV1ciwgdGl0cmUsIGRhdGUgZGUgY3LDqWF0aW9uLCBmb3JtYXQpOiBPbiBwYXJsZSBkZSAqKm3DqXRhZG9ubsOpZXMqKi4gQ2VzIGF0dHJpYnV0cyBkb2l2ZW50IMOqdHJlIHRyYW5zbWlzIMOgIHVuIGxhbmdhZ2UgcXVpIHNlIGNoYXJnZSBkZSBsZXMgc3RvY2tlciBldCBkZSBsZXMgcmVuZHJlIGF1IGRvY3VtZW50IHBvdXIgZW4gY2hhbmdlciBsJ2FzcGVjdCBvdSBham91dGVyIGRlcyBpbmZvcm1hdGlvbnMuIENlIGxhbmdhZ2UsIGMnZXN0IGxlICoqWUFNTCoqIHF1aSBzaWduaWZpYWl0IGF1IGTDqWJ1dCBfWWV0IEFub3RoZXIgTWFya3VwIExhbmd1YWdlXyBtYWlzIHF1aSBlc3QgZGV2ZW51IF9ZQU1MIEFpbnQgTWFya3VwIExhbmd1YWdlXy4gRW4gY2xhaXIgbGUgKipZQU1MKiogYydlc3QgcXVvaT8gVW5lIHN5bnRheGUgcXVpIHBlcm1ldCBkZSBzdG9ja2VyIGRlcyBkb25uw6llcyBzdXIgbGUgZG9jdW1lbnQgZXQgcXVpIGxlcyB1dGlsaXNlIHBvdXIgcGFyYW3DqXRyZXIgbGUgZG9jdW1lbnQgUiBNYXJrZG93biBldCB5IGFqb3V0ZXIgZGVzIGNob3Nlcy4gQ2V0dGUgc3ludGF4ZSBlc3QgdHLDqHMgc3RyaWN0ZSwgYXZlYyBkZXMgZGV1eCBwb2ludHMsIGRlcyByZXRvdXJzIMOgIGxhIGxpZ25lLCBkZXMgZ3VpbGxlbWV0cyBldCBkZXMgaW5kZW50YXRpb25zIChwZXRpdHMgZXNwYWNlcyBhcHLDqHMgbGUgcmV0b3VyIMOgIGxhIGxpZ25lKSBwb3VyIGNpYmxlciBsZXMgc291cy1vcHRpb25zIGQndW5lIG9wdGlvbiBtZXJlLiBQYXIgZXhlbXBsZSwgcG91ciBsZSBgaHRtbF9kb2N1bWVudGAgcXVpIHNpZ25pZmllIGxlIGZvcm1hdCBkZSBzb3J0aWUsIG9uIGEgZGVtYW5kZSBkJ2luY2x1cmUgdW5lIHRhYmxlIGRlcyBtYXRpZXJlcyAoYHRvYzp5ZXNgKSwgbGEgcG9zc2liaWxpdGUgZGUgdGVsZWNoYXJnZXIgbGVzIGNvZGVzIGR1IGRvY3VtZW50IChgY29kZV9kb3dubG9hZCA6IFRSVUVgKS4gTGVzIG9wdGlvbnMgc29udCBlbiBnZW5lcmFsIGxpZWVzIGF1eCBmb3JtYXQgZGUgc29ydGllIGxpZWVzIGF1IGRvY3VtZW50IHF1ZSB2b3VzIHZvdWxleiBvYnRlbmlyLiBDb21tZW50IGxlcyBkb25uw6llcyBzdXIgbGUgZG9jdW1lbnQgc29udCBzdG9ja8OpZXM/IERhbnMgdW4gb2JqZXQgYXBwZWzDqSBgbWV0YWRhdGFgIGRhbnMgbGUgcGFja2FnZSBgcm1hcmtkb3duYC4gUmVnYXJkZXo6CgpgYGB7ciBtZXRhZGF0YX0Kcm1hcmtkb3duOjptZXRhZGF0YSR0aXRsZQpgYGAKCgpQb3VyIHVuIGRvY3VtZW50IEhUTUwsIGlsIGV4aXN0ZSB1bmUgcGzDqXRob3JlIGRlIHBhcmFtw6h0cmVzIChhdXRldXIsIGRhdGUsIGZvbnRlLCBldGMuKSBldCBsJ29uIHBldXQgbcOqbWUgYWpvdXRlciB1biBmaWNoZXIgcXVpIHByZW5kIGJpZW4gZW4gY2hhcmdlIGxhIG1pc2UgZW4gZm9ybWUsIGNvbW1lIG1vbiBmaWNoaWVyIGBzdHlsZS5jc3NgIHF1ZSB2b3VzIHZveWV6IGRhbnMgbCdvcHRpb24gYGNzc2AuIE9uIHBldXQgZW4gZmFpcmUgZGUgbcOqbWUgYXZlYyB1biBmaWNoaWVyIFBERi4gT24gcG91cnJhaXQgw6ljcmlyZSB1biBhcnRpY2xlIGRlc3N1cy4gTWFpcyBlbiBnw6luw6lyYWwgbGUgcGV0aXQgbm9tYnJlIGRlIHBhcmFtw6h0cmVzIHBhciBkw6lmYXV0IHByb3Bvc8OpIHBhciAqUnN0dWRpbyogc3VmZml0IGFtcGxlbWVudCBwb3VyIGRlcyBkb2N1bWVudHMgZGUgcGV0aXRlIGVudmVyZ3VyZS4gRGFucyBsZSBjYXMgb8O5IHZvdXMgdm91bGV6IGRlcyBkb2N1bWVudHMgbG91cmRzLCBpbCBzZXJhaXQgIHNvdWhhaXRhYmxlIGRlIGpldGVyIHVuIGNvdXAgZOKAmcWTaWwgc3VyIGxlcyBwYWdlcyBzdWl2YW50ZXMgYWZpbiBkZSByZWdhcmRlciBjb21tZW50IGNvbnRyw7RsZXIgbGEgbWlzZSBlbiBwYWdlOgoKKiBQb3VyIGxlIGZvcm1hdCBIVE1MLCBbUmVnYXJkZXogaWNpXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL2h0bWxfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoqIFBvdXIgbGUgZm9ybWF0IFBERiwgW1JlZ2FyZGV6IGzDoF0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS9wZGZfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoqIFBvdXIgbGUgZm9ybWF0IFdvcmQsIFtKZXR0ZXogdW4gY291cCBkJ29laWwgbMOgXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL3dvcmRfZG9jdW1lbnRfZm9ybWF0Lmh0bWwpCgoKIyMjIExlcyBjaHVua3MKClVuIGZpY2hpZXIgYHJtYXJrZG93bmAgZXN0IHVuICBmaWNoaWVyIGRhbnMgbGVxdWVsIHNlIHRyb3V2ZW50IGxlcyBjb2RlcyBxdWkgdm9udApwZXJtZXR0cmUgZGUgZ2VuZXJlciBsZXMgYW5hbHlzZXMgZXQgbGVzIHJlc3VsdGF0cyBhc3NvY2llcyBhdXggYW5hbHlzZXMgcHJvcHJlbWVudCAKZGl0ZXMgYWluc2kgcXVlIGxlcyBjb21tZW50YWlyZXMgZGUgY2VzIGFuYWx5c2VzLiBDZXMgY29kZXMgc2UgdHJvdXZlbnQgZGFucyAKZGVzIHBvcnRpb25zIGdyaXNlcyBhcHBlbGVlcyAqKmNodW5rKiosIGFmaW4gZGUgbGVzIGRpc3Rpbmd1ZXIgZGVzIGNvbW1lbnRhaXJlcyAKLSBkdSB0ZXh0ZSBicnV0IC0gcXVlIHZvdXMgZWNyaXZlei4gQ29tbWVudCBpbnNlcmVyIHVuIGNodW5rIGxvcnNxdWUgbCdvbiB0cmF2YWlsbGUKc291cyAqUnN0dWRpbyo/ICoqUG91ciBpbnNlcmVyIHVuIGNodW5rIFIgc291cyBfUnN0dWRpb18sIHV0aWxpc2V6IGxlIHJhY2NvdXJjaSAKY2xhdmllciBgQ1RSTCtBTFQrSWAqKi4gTWFpcyBzaSB2b3VzIHZvdWxleiB+fnZvdXN+fiB0YXBlciBsYSBzeW50YXhlIGRlIApsJ2Vjcml0dXJlLCB1biBjaHVuayBjb21tZW5jZSBwYXIgY2VzIHRyb2lzIGFjY2VudHMgZ3JhdmVzIGBgYGAgYGBgIGBgYGAgc3VpdmlzIApkZSByIHF1ZSBsJ29uIG1ldCBlbnRyZSBkZXMgYWNjb2xhZGVzLCBgYGBgIGBgYHtyfSBgYGBgIGV0IGlsIHNlIHRlcm1pbmUgcGFyIHRyb2lzCmFjY2VudHMgZ3JhdmVzIGF1c3NpIGBgYGAgYGBgIGBgYGAuIFVuZSBlcnJldXIgY29tbXVuZSBlc3QgZGUgbmUgcGFzIHRlcm1pbmVyCnNvbiBjaHVuayBvdSBkJ2VmZmFjZXIgcGFyIG1hbGFkcmVzc2UgbGVzIHRyb2lzIGFjY2VudHMgZGUgbGEgZmluLiAKCkxlcyBjaHVuayBwZXV2ZW50IGF2b2lyIGRlcyBvcHRpb25zIGVuIGZvbmN0aW9uIGRlIGNvbW1lbnQgbCdvbiB2ZXV0IHRyYWl0ZXIgbGUgCnJlbmR1LiBFbiBnZW5lcmFsIG9uIHBldXQgc29pdCB2b3Vsb2lyIGFmZmljaGVyIGxlIGNvZGUgb3UgcGFzLCBzb2l0IGxhIHNvcnRpZSAKZHUgY29kZSBvdSBwYXMsIHNvaXQgZXZhbHVlciBsZSBjb2RlIG91IHBhcy4gVm91cyBwb3V2ZXogcGFyY291cmlyIGxlcyBvcHRpb25zIApkJ3VuIGNodW5rIFIgcXVlIHZvdXMgYXVyZXogaW5zZXJlIGVuIGNsaXF1YW50IHN1ciBsZXMgcGFyYW1ldHJlcyBkdSBjaHVuay4KCjxjZW50ZXI+CiFbXVtDaHVua1BhcmFtZXRlcnNdCjwvY2VudGVyPgoKVW5lIGZvaXMgcXVlIHZvdXMgdmVycmV6IGNvbW1lbnQgbGVzIG9wdGlvbnMgb250IGV0ZSBpbnNlcmVlcywgdm91cyBwb3V2ZXogdGFwZXIKbGUgY29kZSB2b3VzIG1lbWUuIE9uIGEgZG9uYyByZWNoYXJnZSBub3RyZSBiYXNlIGRlIGRvbm5lZXMgZW4gdXRpbGlzYW50IApsZSBjaHVuayBzdWl2YW50OgoKPGNlbnRlcj4KIVtdW0NodW5rSW5zZXJ0aW9uXQo8L2NlbnRlcj4KCiAgICAgICAgCkxlcyBjaHVua3MgcGFyIGRlZmF1dCwgc3VwcG9zZW50IHF1ZSB2b3VzIGF2ZXogZHUgUiBjb21tZSBsYW5nYWdlLCBtYWlzIGlsIGVzdCBwb3NzaWJsZSBkZSBjcmVlciBkZXMgY2h1bmNrcyBhdmVjIGQnYXV0cmVzIGxhbmdhZ2VzLiAgVm91cyBwb3V2ZXogY2hvaXNpciBsZSBsYW5nYWdlIGFzc29jaWUgYXUgY2h1bmsgCnF1ZSB2b3VzIHZvdWxleiBpbnNlcmVyIGVuIGNsaXF1YW50IHN1ciAqKmluc2VydCoqIGVuIGhhdXQgYSBnYXVjaGUgZGUgbCdlZGl0ZXVyLiBFbiBiYXMgcGFyIGV4ZW1wbGUsIGonaW5zZXJlIHVuIGNodW5rIGF2ZWMgZGVzIGNvbW1hbmRlcyBzeXN0ZW1lcy4KCjxjZW50ZXI+CiFbXVtDaHVua0VuZ2luZV0KPC9jZW50ZXI+CgpgYGB7YmFzaCBjaHVua3MtYmFzaH0KY2Qgfi9Eb2N1bWVudHMKbHMKCmBgYAoKClNpIHZvdXMgZmFpdGVzIGRlIG1lbWUsIHZvdXMgdmVycmV6IHF1ZSB2b3RyZSBjaHVuayBjb21tZW5jZSBwYXIgYGBgYCBgYGB7YmFzaH0gYGBgYC4KQ2VsYSBwZXJtZXQgYSBrbml0ciBkZSBzYXZvaXIgcXVlbCBsYW5nYWdlIHV0aWxpc2UgZGFucyBsZSBjaHVuay4gCgpMZXMgY2h1bmsgcGV1dmVudCBhdm9pciB1biBub20uIEwnaWRlZSBlc3QgZGUgbGV1ciBwZXJtZXR0cmUgZCdldHJlIGZhY2lsZW1lbnQgCmFjY2Vzc2libGUgZW4gdXRpbGlzYW50IGxlcyBvbmdsZXRzIGRlIG5hdmlnYXRpb24gZGUgKlJzdHVkaW8qLiBQb3VyIG5vbW1lciB1biAKY2h1bmssIGlsIHN1ZmZpdCBkZSBtZXR0cmUgCgojIyMgTGUgY2h1bmsgc2V0dXAKCiMjIyBEZXMgbGlzdGVzIGV0IGRlcyBmb3JtdWxlcwoKT24gcGV1dCBmYWlyZSBkZXMgbGlzdGVzIGF2ZWMgdW4gZmljaGllciBSIE1hcmtkb3duIGRlIGZhw6dvbiB0csOocyBmYWNpbGU6CgpgYGAKVW5lIGxpc3RlIG51bcOpcm90w6llOgoKMS4gVW4KMi4gRGV1eAozLiBUcm9pcwozLiBRdWF0cmUKClZvdXMgcmVtYXJxdWVyZXogcXUnaWwgYXVnbWVudGUgZW4gbcOqbWUgdGVtcHMgbGUgY2hpZmZyZSBub24/CgpFdCBkZXMgbGlzdGVzIG5vbiBudW3DqXJvdMOpZXMgY29tbWUgYXZlYyBkZXMgdGlyZXRzOgoKLSBVbgotIERldXgKLSBUcm9pcwoKT3UgYXZlYyBkZXMgcG9pbnRzOgoKKiBVbgoqIERldXgKKiBUcm9pcwoKT3UgbGVzIGRldXg6CgoqIEonYWltZSBsYSBiaW9zdGF0aXN0aXF1ZQogICAgKyBMZXMgZWxldmVzIG4nb250IHBhcyBpbnN0YWxsZXIgbGVzIHBhY2thZ2VzCiAgICArIENvdWNvdSBhIHRvdXMuCiAgCiogSWwgc2FpdCBtZXR0cmUgbGEgZGlmZsOpcmVuY2UgZW50cmUgbGVzIHJvbmRlcyBibGFuY2hlcyBldCBsZXMgbm9pcmVzLiBJbCBzdWZmaXQgZCdhbGxlciDDoCBsYSBsaWduZSBldCBkZSBtZXR0cmUgZGV1eCBpbmRlbnRhdGlvbnMgYXZlYyBsZSBgYmFja3NwYWNlYCAobCdhY2NlbnQgZ3JhdmUgZXN0IHBvdXIgbWV0dHJlIGVuIGV4ZXJndWUpIHBvdXIgYXZvaXIgZGVzIHNvdXMtbGlzdGVzLgpgYGAKCkxlIHRleHRlIHByw6ljw6lkZW50IGRvbm5lIGxhIHNvcnRpZSBzdWl2YW50ZToKCmBgYHtibG9jaywgdHlwZT0gIm1vbnR5cGUyIn0KVW5lIGxpc3RlIG51bcOpcm90w6llOgoKMS4gVW4KMi4gRGV1eAozLiBUcm9pcwozLiBRdWF0cmUKClZvdXMgcmVtYXJxdWVyZXogcXUnaWwgYXVnbWVudGUgZW4gbcOqbWUgdGVtcHMgbGUgY2hpZmZyZSBub24/CgpFdCBkZXMgbGlzdGVzIG5vbiBudW3DqXJvdMOpZXMgY29tbWUgYXZlYyBkZXMgdGlyZXRzOgoKLSBVbgotIERldXgKLSBUcm9pcwoKT3UgYXZlYyBkZXMgcG9pbnRzOgoKKiBVbgoqIERldXgKKiBUcm9pcwoKT3UgbGVzIGRldXg6CgoqIEonYWltZSBsYSBiaW9zdGF0aXN0aXF1ZQogICAgKyBMZXMgZWxldmVzIG4nb250IHBhcyBpbnN0YWxsZXIgbGVzIHBhY2thZ2VzCiAgICArIENvdWNvdSBhIHRvdXMuCiAgCiogSWwgc2FpdCBtZXR0cmUgbGEgZGlmZsOpcmVuY2UgZW50cmUgbGVzIHJvbmRlcyBibGFuY2hlcyBldCBsZXMgbm9pcmVzLiBJbCBzdWZmaXQgZCdhbGxlciDDoCBsYSBsaWduZSBldCBkZSBtZXR0cmUgZGV1eCBpbmRlbnRhdGlvbnMgYXZlYyBsZSBgYmFja3NwYWNlYCBwb3VyIGF2b2lyIGRlcyBzb3VzLWxpc3Rlcy4KCmBgYAoKLS0tCgpPbiBwZXV0IGZhaXJlIGR1IHBkZiBiYXNlIHN1ciBkdSAkXExhVGVYJCBkYW5zIHJtYXJrZG93biwgY29tbWUgamUgbCdhdmFpcyBkaXQgZW4gbW9udHJhbnQgY2V0dGUgaW1hZ2UgW2ljaV1bT3V0cHV0Rm9ybWF0XS4KPGEgbmFtZT0ibGllbnZlcnNsZWhhdXQiLz4KPC9hPgpPbiBwZXV0IGluc8OpcmVyIGRlcyBmb3JtdWxlcyAkXExhVGVYJCBkYW5zIHVuIGRvY3VtZW50IFIgTWFya2Rvd24gcGV1IGltcG9ydGUgbGUgZm9ybWF0IGRlIHNvcnRpZSwgZW4gdXRpbGlzYW50IGxhIG3Dqm1lIHN5bnRheGUgcXVlIGNlbGxlIGRlIExhVGVYOgoKYGBgCiRcc3VtX3tpPTF9Xm5cYWxwaGFfaSQ7CgokdGFuKHgpPVxmcmFje2Nvcyh4KX17c2luKHgpfSQKYGBgCgoKYGBge2Jsb2NrLCB0eXBlPSJtb250eXBlMiJ9CiRcc3VtX3tpPTF9Xm5cYWxwaGFfaSQ7CgokdGFuKHgpPVxmcmFje2Nvcyh4KX17c2luKHgpfSQKYGBgCgoKIyMjIEluc8OpcmVyIGRlcyBJbWFnZXMsIEluc8OpcmVyIGRlcyB0YWJsZWF1eAoKTGUgZmljaGllciBxdWUgdm91cyBsaXNleiBlc3QgcGxlaW4gZCdpbWFnZXMgcXVpIHBlcm1ldHRlbnQgZCdpbGx1c3RyZXIgbGVzIHByb3Bvcy4gT24gcGV1dCBpbnPDqXJlciBkZXMgaW1hZ2VzIGRhbnMgdW4gZmljaGllciBSIE1hcmtkb3duLiBQb3VyIGNlbGEgaWwgZmF1dCBkb25uZXIgdW4gaWRlbnRpZmlhbnQgw6AgbCdpbWFnZSAoY29tbWUgcGFyIGV4ZW1wbGUgYG1vbmltYWdlYCkgZXQgbOKAmWluc8OpcmVyIGRhbnMgbGUgZG9jdW1lbnQgZGUgbGEgZmHDp29uIHN1aXZhbnRlOgoKYGBgCiFbTGUgdGl0cmUgZGUgbCdpbWFnZV1bbW9uaW1hZ2VdCmBgYAoKTWFpcyBjb21tZW50IFIgTWFya2Rvd24gcmV0cm91dmUgbCdpbWFnZSBjb3JyZXNwb25kYW50ZT8gRW4gbWV0dGFudCDDoCAqKmxhIGZpbiBkdSBmaWNoaWVyKiogbGVzIHLDqWbDqXJlbmNlcyBwZXJtZXR0YW50IGQnYXR0ZWluZHJlIGwnaW1hZ2UuIExhIHN5bnRheGUgZXN0IGxhIHN1aXZhbnRlIHBvdXIgdW4gZm9ybWF0IHBuZyBwYXIgZXhlbXBsZS4KCmBgYApbbW9uaW1hZ2VdOiBDaGVtaW5fdmVyc19saW1hZ2UvaW1hZ2UucG5nICJUZXh0ZSBwb3B1cCBxdWkgcydhZmZpY2hlIHF1YW5kIGxhIHNvdXJpcyBzdXJ2b2xlIgpgYGAKCkwnaWRlbnRpZmlhbnQgcGV1dCDDqnRyZSB1dGlsaXPDqSBwb3VyIGluZGV4ZXIgbCdpbWFnZSDDoCB0cmF2ZXJzIHVuIGxpZW4gZGFucyBsZSBkb2N1bWVudCwgY29tbWUgaidhaSBmYWl0IHBvdXIgW2ljaV0oI2xpZW52ZXJzbGVoYXV0KQoKIyMjIyBMZXMgVGFibGVhdXgKCklsIGV4aXN0ZSBwbHVzaWV1cnMgbWFuacOocmVzIGQnaW5zw6lyZXIgdW4gdGFibGVhdSwgbGEgZmHDp29uIGxhIHBsdXMgcmVjb21tYW5kw6llIMOpdGFudCBkJ3V0aWxpc2VyIGxlIHBhY2thZ2UgYGtuaXRyYCBjb21tZSBwcsOpc2VudMOpIFtwcsOpY8OpZGVtbWVudF0oI2xpZW52ZXJzbGV0YWJsZWF1KS4gCkNlcGVuZGFudCwgaWwgZXN0IHBvc3NpYmxlIGQnaW5zw6lyZXIgdW4gdGFibGVhdSBkYW5zIHVuIGRvY3VtZW50IFIgTWFya2Rvd24gZGUgbGEgZmHDp29uIHN1aXZhbnRlLCBvdSBsZXMgZGV1eCBwb2ludHMgcGVybWV0dGVudCBkZSBkaXJlIGNvbW1lbnQgbCdvbiB2ZXV0IGFsaWduZXIgbGVzIGVsZW1lbnRzIGR1IHRhYmxlYXUuCgpgYGAKOiBVbiBUYWJsZWF1Cgp8QWxpZ27DqSDDoCBEcm9pdGV8QWxpZ27DqSDDoCBHYXVjaGV8UGFyIETDqWZhdXR8QXUgQ2VudHJlfAp8LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfDotLS0tLS0tOnwKfEluc3RhbGxleiAgICAgIHxOJ291YmxpZXogcGFzICB8UGFja2FnZSAgICB8IGxlcyAgICAgfAp8bGVzICAgICAgICAgICAgfERpbnN0YWxsZXIgICAgIHxJbnN0YWxsZXogIHxwYWNrYWdlICAgIHwKfHBhY2thZ2UgICAgICAgIHxsZXMgICAgICAgICAgICB8YXZhbnQgZGUgdmVuaXJ8NSAgICAgIHwKCgoKYGBgCgpgYGB7YmxvY2ssIHR5cGU9Im1vbnR5cGUyIn0KOiBVbiBUYWJsZWF1Cgp8QWxpZ27DqSDDoCBEcm9pdGV8QWxpZ27DqSDDoCBHYXVjaGV8UGFyIETDqWZhdXR8QXUgQ2VudHJlfAp8LS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tfDotLS0tLS0tOnwKfEluc3RhbGxleiAgICAgIHxOJ291YmxpZXogcGFzICB8UGFja2FnZSAgICB8IGxlcyAgICAgfAp8bGVzICAgICAgICAgICAgfERpbnN0YWxsZXIgICAgIHxJbnN0YWxsZXogIHxwYWNrYWdlICAgIHwKfHBhY2thZ2UgICAgICAgIHxsZXMgICAgICAgICAgICB8YXZhbnQgZGUgdmVuaXJ8NSAgICAgIHwKCmBgYAoKLS0tCgojIyMgTGVzIHBldGl0cyBwbHVzIHBvdXIgZmluaXIKCiMjIyMgVW4gZmljaGllciBjb21tZSBjZWx1aS1jaSAuLi4gT24gZmFpdCBjb21tZW50PwoKUG91ciBjcsOpZXIgdW4gZmljaGllciBjb21tZSBjZWx1aS1jaSwgcmllbiBkZSBwbHVzIHNpbXBsZSEgQ3LDqWV6IHVuIGRvY3VtZW50IFIgTWFya2Rvd24gbm9ybWFsIGV0IGFqb3V0ZXogcXVlbHF1ZXMgcGFyYW3DqHRyZXMgcG91ciBsZSByZW5kcmUgcGx1cyBhdHRyYWN0aWYuIEonYWkgZCdhYm9yZCBjaGFuZ8OpIGxlIHRow6htZSBnw6luw6lyYWwgZW4gY2hvaXNpc3NhbnQgbGUgdGjDqG1lIGBmbGF0bHlgIHF1ZSBqJ2FpbWUgYmllbi4gUG91ciBjZWxhLCBpbCBmYXV0IGFqb3V0ZXIgbGEgc3ludGF4ZSBgdGhlbWU6IGZsYXRseWAgZGFucyBsZSBibG9jICoqWUFNTCoqLiBKJ2FpIGF1c3NpIGFqb3V0ZXIgbGEgdGFibGUgZGVzIG1hdGnDqHJlcywgYWluc2kgcXUndW4gZMOpZmlsZW1lbnQgcGx1dMO0dCBpbnTDqXJlc3NhbnQgZGUgbGEgdGFibGU6CgpgYGAKLS0tCiMgTGUgaGF1dCBkZSBsYSBzeW50YXhlCnRvYzogdHJ1ZQp0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlOiB0cnVlCiAgICAgIHNtb290aF9zY3JvbGw6IHRydWUKLS0tCmBgYAoKTGEgbWlzZSBlbiBmb3JtZSBkZSBsYSBwYWdlIGV0IGxlIHN0eWxlIG9udCDDqXTDqSBnw6lyw6lzIGF2ZWMgdW4gZmljaGllciBkZSBjb25maWd1cmF0aW9uLCBhcHBlbMOpIGBzdHlsZS5jc3NgLiBBIHF1b2kgc2VydCB1biBmaWNoaWVyIC5jc3M/IEEgZMOpZmluaXIgbGEgbWlzZSBlbiBwYWdlIGRlIHBhZ2VzIHdlYi4gSidhaSBqdXN0ZSB1dGlsaXPDqSBxdWVscXVlcyBicmliZXMgZGUgY29ubmFpc3NhbmNlIGRhbnMgbGUgZG9tYWluZSBwb3VyIGfDqXJlciBsYSBtaXNlIGVuIHBhZ2UuIExlIGNzcyBwZXV0IMOgIGx1aSB0b3V0IHNldWwgZmFpcmUgbCdvYmpldCBkJ3VuIGF1dHJlIGZpY2hpZXIgdHV0b3JpZWwuIE1haXMgcGFzIGJlc29pbiBkZSBncmFuZCBjaG9zZXMgcG91ciB1bmUgbWlzZSBlbiBmb3JtZSBjb21tZSBjZWxsZSB1dGlsaXPDqWUgZGFucyBjZSBkb2N1bWVudC4gSWwgc3VmZml0IGp1c3RlIGRlIFtqZXRlciB1biBjb3VwIGQnb2VpbF0oc3R5bGUuY3NzKSBzdXIgbW9uIGZpY2hpZXIgcG91ciB2b3VzIGVuIHJlbmRyZSBjb21wdGUuIERhbnMgbGUgZmljaGllciBjc3MsYGJvZHlgIHJlcHLDqXNlbnRlIGxlIGNvcnBzIGR1IGRvY3VtZW50IGV0IGxlcyBwcm9wcmnDqXTDqXMgZMOpZmluaXNzZW50IGNvbW1lbnQgbGUgZG9jdW1lbnQgZXN0IGZvcm1hdMOpLiBBaW5zaSwgbW9uIGRvY3VtZW50IGVzdCBtaXMgZW4gZm9udGUgR2VvcmdpYSwgMTNwdCwgZXQgICoqanVzdGlmacOpKiogYXZlYyBsYSBzeW50YXhlIHN1aXZhbnRlOgoKYGBgCmJvZHl7CiAgZm9udC1mYW1pbHk6IEdlb3JnaWE7CiAgZm9udC1zaXplOiAxM3B0OwogIHRleHQtYWxpZ246IGp1c3RpZnk7Cn0KYGBgCgpgaDFgLCBgaDJgLCBgaDNgIGTDqXNpZ25lbnQgbGVzIHNlY3Rpb25zIGV0IHNvdXMgc2VjdGlvbnMgZGUgbml2ZWF1eCAxLDIsMyByZXNwZWN0aXZlbWVudC4gSidhaSBnw6lyw6kgYXVzc2kgbGEgbWlzZSBlbiBmb3JtZSBkZSBjZXJ0YWlucyBibG9jcyBkYW5zIGxlIGZpY2hpZXIgY3NzLiBDZWxhIGZlcmEgbCdvYmpldCBkZSBsYSBzZWN0aW9uIHN1aXZhbnRlLiBQb3VyIHBsdXMgZCdpbmZvcm1hdGlvbnMgc3VyIGxlIGNzcywgcmVuZGV6LXZvdXNbXjRdIHN1ciBsYSBwYWdlIFtsw6BdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2ZyL0FwcHJlbmRyZS9DU1MpLiBSZXN0ZSDDoCBpbmNsdXJlIGxlIGZpY2hpZXIgZGFucyBsZSBkb2N1bWVudCDDoCB0cmF2ZXJzIGxhIHN5bnRheGUgKipZQU1MKiogYGNzczogc3R5bGUuY3NzYCBhcHLDqHMgbCdhdm9pciBtaXMgZGFucyBsZSBtw6ptZSByw6lwZXJ0b2lyZSBxdWUgbGUgZmljaGllciBSIE1hcmtkb3duLgoKIyMjIyBMYSBtaXNlIGVuIGZvcm1lIGRlcyBibG9jcwoKTGEgbWlzZSBlbiBmb3JtZSBkZXMgYmxvY3Mgcydlc3QgZmFpdGUgZW4gdXRpbGlzYW50IGF1c3NpIGR1IGBjc3NgLiAgTGUgcGFja2FnZSBga25pdHJgIHBlcm1ldCBkJ2luc8OpcmVyIGQnYXV0cmVzIGxhbmdhZ2VzIHF1ZSBkdSBSIGRhbnMgbGVzIGJsb2NzIGRlIGNvZGUgKipldCBtw6ptZSBkZSBsZXMgZXjDqWN1dGVyIMOgIHRyYXZlcnMqKiB1biBzeXN0w6htZSBub21tw6kgW2VuZ2luZV0oaHR0cHM6Ly95aWh1aS5uYW1lL2tuaXRyL2RlbW8vZW5naW5lcy8pLiBJbCBlc3QgYXVzc2kgcG9zc2libGUgZGUgY3LDqWVyIGRlcyBibG9jcyB2aWRlcywgbm9uIGNvbmZvcm1lcyDDoCB1biBsYW5nYWdlIHByw6ljaXMgb3UgZGVzIGJsb2NzIHByb3ByZXMgZm9ybWF0w6lzIGVuIE1hcmtkb3duLiBDJ2VzdCBjZSBxdWkgYSDDqXTDqSBmYWl0IGRhbnMgbGVzIGJsb2NzIGVuIG1hcnJvbiBkYW5zIGxlIGRvY3VtZW50LiBQb3VyIGNyw6llciB1biBibG9jIHByb3ByZSBlbiBNYXJrZG93biwgZGFucyBsZSBmaWNoaWVyIFIgTWFya2Rvd24gb24gw6ljcml0IHVuIGJsb2Mgc3VpdmFudDoKCgpgYGAKYGBgYHtibG9jaywgdHlwZT0idW50eXBlIn0KbiA9IDEwCnJub3JtKG4pCmBgYGAKYGBgCgpJbCBmYXV0IGVuc3VpdGUgZmFpcmUgbGEgbWlzZSBlbiBmb3JtZSBlbiB5IGRhbnMgam9pZ25hbnQgbGUgZmljaGllciBgLmNzc2AgbGEgZm9ybWUgZMOpZGnDqWUgYXUgYmxvYyBgdW50eXBlYC4gRGFucyBsZSBmaWNoaWVyIGAuY3NzYCwgb24gcG91cnJhIGRvbmMgw6ljcmlyZSBsZXMgYmxvY3MgZGUgY29kZSBzdWl2YW50czoKCmBgYAoudW50eXBlewogIGJhY2tncm91bmQtY29sb3I6ICNmOWY1ZjM7CiAgZm9udC1zaXplOjEycHQ7CiAgZm9udC1mYW1pbHk6ICJHZW9yZ2lhIiwgc2VyaWY7CiAgcGFkZGluZy10b3A6NXB4OwogIHBhZGRpbmctbGVmdDo4cHg7CiAgYm9yZGVyLWxlZnQ6IDVweCBzb2xpZCAjZThkYWQxOwogIHBhZGRpbmctYm90dG9tOjVweDsKICBwYWRkaW5nLXJpZ2h0OjVweDsKfQpgYGAKCkFpbnNpLCDDoCBjaGFxdWUgZm9pcyBxdWUgbCdvbiBjaG9pc2lyYSB1biBibG9jIGRlIHR5cGUgYHVudHlwZWAsIGlsIGF1cmEgbGVzIHByb3ByacOpdMOpcyBjaXTDqXMgcGx1cyBoYXV0LgoKCiMjIyMgRXQgcG91ciB1biBkb2N1bWVudCBsb3VyZD8gT3UgdW4gYXJ0aWNsZT8KCgoKTidleGFnw6lyb25zIHJpZW4sIG1lIGRpcmV6LXZvdXMuLi4uIFBvdXJxdW9pIHLDqWRpZ2VyIHVuIGxpdnJlIGVudGllciBvdSB1biBhcnRpY2xlIGRhbnMgKlJzdHVkaW8qIGFsb3JzIHF1J29uIGEgV29yZD8KCioqUGFyY2UgcXVlIGMnZXN0IHJlcHJvZHVjdGlibGUqKgoKVm91cyB2b3VzIHJlbmRlei1jb21wdGUgZCd1bmUgZXJyZXVyPyBVbmUgbW9kaWZpY2F0aW9uIGV0IMOnYSB5IGVzdCEgdG91dCBlc3QgcsOpZ2zDqS4gUGFzIGRlIGNvcGllciBjb2xsZXIgYXZlYyBkZXMgcGVydGVzIGRlIHRlbXBzIGV0IGRlcyByaXNxdWVzIGQnZXJyZXVycy4gQXVzc2ksIHZvdXMgcG91dmV6IGp1c3RlIGJhbGFuY2VyIGxlIGNvZGUgw6AgdW4gYW1pIGV0IGlsIHBldXQgcmVwcmVuZHJlIGxlcyBtw6ptZXMgYW5hbHlzZXMgZXQgb2JzZXJ2ZXIgc2kgdm91cyBhdmV6IHRvdXQgYmllbiBmYWl0LCBvdSBsb3VwZXogcXVlbHF1ZSBjaG9zZS4uLiDDh2EgbidhcnJhbmdlIHF1ZSBsYSByZWNoZXJjaGUuCgpSZXZlbm9ucyBhdSB0aXRyZSwgY29tbWVudCByw6lkaWdlciB1biBhcnRpY2xlIHNvdXMgUiBNYXJrZG93bi4gTG9yc3F1ZSB2b3VzIGTDqWNpZGV6IGRlIGNyw6llciB1biBub3V2ZWF1IGRvY3VtZW50IHNvdXMgUiBNYXJrZG93biwgdm91cyBhdmV6IHVuZSBwYWdlIHN1aXZhbnRlIGNvcnJlc3BvbmRhbnQgYXUgZG9jdW1lbnQgcXVlIHZvdXMgdm91bGV6OgoKIVtdW1RlbXBsYXRlXQoKRW4gYmFzLCB2b3VzIHBvdXZleiBjaG9pc2lyIGwnb3B0aW9uIF9Gcm9tIFRlbXBsYXRlXyBwb3VyIGNyw6llciBsZSBkb2N1bWVudCDDoCBwYXJ0aXIgZCdleGVtcGxhaXJlcyBleGlzdGFudCBkw6lqw6AuIENldHRlIHNlY3Rpb24gbm91cyBwZXJtZXQgZGUgY2hvaXNpciB1biBlbnNlbWJsZSBkJ2V4ZW1wbGFpcmVzIGV0IGRlIGxlcyB1dGlsaXNlciDDoCBvdXRyYW5jZSBsb3JzcXVlIHZvdXMgc291aGFpdGV6IGZhaXJlIHVuIG5vdXZlYXUgZG9jdW1lbnQgUiBNYXJrZG93biwgZW4gcGFzc2FudCBvdXRyZSBsZSBmb3JtYXQgYmFzaXF1ZSBxdWUgKlJzdHVkaW8qIHByb3Bvc2UuIAoKW1F1J2VzdCBjZSBxdSd1biBfVGVtcGxhdGVfIGRlIFIgbWFya2Rvd24/XShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tL2RldmVsb3Blcl9kb2N1bWVudF90ZW1wbGF0ZXMuaHRtbD92ZXJzaW9uPTEuMC4xMzYmbW9kZT1kZXNrdG9wKQoKQydlc3QgdW4gZW5zZW1ibGUgZGUgZm9ybWF0cyBldCBkZSBwcm9wcmnDqXTDqXMgcHLDqWTDqWZpbmlzIHF1aSB2b3VzIHBlcm1ldHRlbnQgZCdhY2PDqWzDqXJlciBsZSB0cmF2YWlsIHNpIHZvdXMgYXZleiBsJ2hhYml0dWRlIGQnw6ljcmlyZSBkZXMgZG9jdW1lbnRzIHF1aSBvbnQgbGEgbcOqbWUgc3RydWN0dXJlLiBPbiBwZXV0IGVuIGNyw6llciB1biBhdmVjIFIgTWFya2Rvd24sIG1haXMgY2VsYSBuw6ljZXNzaXRlIHVuIHBldSBkZSB0d2Vhay4uLiAKClZvdXMgcG91dmV6IG7DqWFubW9pbnMgdXRpbGlzZXIgZGVzIF9UZW1wbGF0ZV8gZXhpc3RhbnRzLCBlbiBpbnN0YWxsYW50IGxlIHBhY2thZ2UgYHJ0aWNsZXNgIHBhciBleGVtcGxlIHF1aSB2b3VzIHBlcm1ldHRyYSBkJ2F2b2lyIGxlcyBmb3JtYXRzIHByw6lkw6lmaW5pcyBwb3VyIGxlcyBhcnRpY2xlcyBkYW5zIGRpZmbDqXJlbnRzIGpvdXJuYXV4LiBTaSB2b3VzIHBlbnNleiBwdWJsaWVyIGRhbnMgdGVsIG91IHRlbCBqb3VybmFsLCB2b3VzIHBvdXZleiBkw6lmaW5pciB1biBUZW1wbGF0ZSBwb3VyIGNlIGpvdXJuYWwgcydpbCBuJ2V4aXN0ZSBwYXMgZXQgcsOpZGlnZXIgYXZlYywgb3UgbcOqbWUgbGUgcGFydGFnZXIuIEluc3RhbGxleiBsZSBwYWNrYWdlIGBydGljbGVzYCwKCmBgYHtyLCB3YXJuaW5nPUZBTFNFLCBldmFsPUZBTFNFfQoKICBpbnN0YWxsLnBhY2thZ2VzKCJydGljbGVzIiwgdHlwZT0ic291cmNlIikKCmBgYAoKUHVpcyB2b3VzIHZlcnJleiBsZXMgZXhlbXBsYWlyZXMgcG91ciBsZXMgYXJ0aWNsZXMgZGFucyBsYSBzZWN0aW9uIGBGcm9tIFRlbXBsYXRlYC4gUG91ciBsZSByZXN0ZSwgw6Agdm91cyBkZSBqb3Vlci4gVm91cyBwb3V2ZXogYWpvdXRlciBkJ2F1dHJlcyBUZW1wbGF0ZXMgZW4gZmFpc2FudCB1biB0b3VyIHN1ciBsYSBbZ2FsbGVyaWUgZGUgUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbS9nYWxsZXJ5Lmh0bWwpLgoKIyMgTGUgYm9va2Rvd24KClBldXQtb24gZWNyaXJlIHVuIGxpdnJlIGF2ZWMgZHUgcm1hcmtkb3duPyBPdWksIGMnZXN0IHBvc3NpYmxlLiBFdCBwb3VyIHJlbmRyZSBsZSB0b3V0IGJlYXUsIGF2ZWMgZHUgYGJvb2tkb3duYC4gW0pldGV6LXZvdXMgcG91ciByZWdhcmRlcl0oaHR0cHM6Ly9ib29rZG93bi5vcmcvKS4gU2kgdm91cyB2b3VsZXoganVzdGUgYWNxdWVyaXIgbGVzIGJhc2VzIG5lY2Vzc2FpcmVzIHBvdXIgcmVkaWdlciwgb24gY29udGludWUuCgoKCgojIyBMZSBibG9nZG93bgoKCgojIyBMZSB0aWR5dmVyc2UKCgojIyBMZXMgZmlndXJlcyBhdmVjIGBnZ3Bsb3QyYAoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25nZ3Bsb3QyIi8+CjwvYT4KCgoKIyMgTGVzIHRlc3RzIHN0YXRpc3RpcXVlcwoKPGEgbmFtZT0ibGllbnZlcnNsZXNzdGF0cyIvPgo8L2E+CgoKIyMgTGEgY3JlYXRpb24gZGUgcGFja2FnZSBzb3VzICpSc3R1ZGlvKgoKPGEgbmFtZT0ibGllbnZlcnNsYXNlY3Rpb25wYWNrYWdlIi8+CjwvYT4KCgojIyBMZXMgcGV0aXRzIHBsdXMgcG91ciBmaW5pci4uLgoKSmUgbmUgc2F1cmFpcyB0ZXJtaW5lciBzYW5zIGRvbm5lciB1bmUgZG9jdW1lbnRhdGlvbiBwb3VyIGNldXggZXQgY2VsbGVzIHF1aSAKdmV1bGVudCBhcHByb2ZvbmRpciBsZXVyIGNvbm5haXNzYW5jZSBlbiBzdGF0cyBldCBSLgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKW0xhbmNlUm1hcmtdOiBmaWd1cmVzL091dnJpcl9GaWNoaWVyLnBuZyAiTGFuY2VtZW50IGRlIHJtYXJrZG93biIKW1BhcmFtZXRyZV06IGZpZ3VyZXMvUGFyYW1ldHJlLnBuZyAiQ2hvaXggZGVzIHBhcmFtw6h0cmVzIGR1IGZpY2hpZXI6IHRpdHJlLCBhdXRldXIsIGV0Yy4iCltGaWNoaWVyQmFzaXF1ZV06IGZpZ3VyZXMvRmljaGllckJhc2lxdWUucG5nICJMZSBmaWNoaWVyIHN1ciBsZXF1ZWwgdm91cyB2b3VzIGJhc2V6IHBvdXIgY3LDqWVyIHVuIGRvYyBybWFya2Rvd24iCltPdXRwdXRGb3JtYXRdOiBmaWd1cmVzL3JtZF9vdXRwdXRfZm9ybWF0cy5wbmcgIkxlcyBmb3JtYXRzIGRlIHNvcnRpZSBkZSBybWFya2Rvd24iCltSbWRTeW50YXhdOiBmaWd1cmVzL21kU3ludGF4LnBuZwpbQ2h1bmtQYXJhbWV0ZXJzXTogZmlndXJlcy9wYXJhbWV0cmVzX2NodW5rLnBuZwpbUHJvamV0UnN0dWRpb106IGZpZ3VyZXMvcHJvamVjdF9jcmVhdGlvbi5wbmcKW0NodW5rRW5naW5lXTogZmlndXJlcy9DaHVua0VuZ2luZS5wbmcgIkxlcyBkaWZmZXJlbnRzIGxhbmdhZ2VzIGFzc29jaWVzIGF1eCBjaHVua3MiCltDaHVua0luc2VydGlvbl06IGZpZ3VyZXMvQ2h1bmtJbnNlcnRpb24ucG5nIAoKClteMV06IExlIGByZWFkbWUudHh0YCBxdWUgaidhaSBham91dGUgbidlc3QgcGFzIG9ibGlnYXRvaXJlLCBtYWlzIGlsIHNlcmFpdCBpbnRlcmVzc2FudCBkJ2V4cGxpcXVlcgphdXggZ2VucyBsZSBkb3NzaWVyIGV0IGNlIHF1J2lsIHkgYSBsJ2ludGVyaWV1ciwgb3UgbWVtZSB0b24gZnV0dXIgdG9pIHF1aSBuZSBjb21wcmVuZHJhaXQgcGx1cyByaWVuCmRhbnMgcXVlbHF1ZXMgYW5uZWVzIGF1IHRyYXZhaWwgcXVlIHR1IGF2YWlzIGZhaXQuIENlcnRhaW5zIGVuIGZvbnQgdW4gYHJlYWRtZS5odG1sYCAoZWNyaXQgZW4gbWFya2Rvd24pLCBkJ2F1dHJlcyB1biBgcmVhZG1lLnR4dGAuCgpbXjJdOiBMaWJyZSBhIHZvdXMgZCdvcmdhbmlzZXIgdm90cmUgZG9zc2llciBkZSB0cmF2YWlsIGNvbW1lIHZvdXMgdm91bGV6LCBwb3VydnVlIHF1ZQp2b3VzIGdhcmRpZXogdW5lIGNlcnRhaW5lIHJpZ3VldXIgZGFucyBsJ29yZ2FuaXNhdGlvbi4gSmUgcHJlc2VudGUgaWNpIG1vbiB3b3JrZmxvdyBoYWJpdHVlbCAoUGFzCnZyYWltZW50IHB1aXNxdWUgZGFucyBtb24gd29ya2Zsb3cgaGFiaXR1ZWwsIGxlIGRvc3NpZXIgYGRhdGFgIHNlIHRyb3V2ZSBkYW5zIGBpbnB1dGApCgpbXjNdOiBDZXR0ZSBzZWN0aW9uIHByb3ZpZW50IGQndW4gZG9jdW1lbnQgZXhwbGljYXRpZiBzdXIgbGUgTWFya2Rvd24gcXVlIGonYXZhaXMgZWNyaXMKcHJlYWxhYmxlbWVudC4gTGVzIHBlcnNvbm5lcyBxdWkgdHJvdXZlcmFpZW50IHVuZSBxdWVsY29ucXVlIHNpbWlsaXR1ZGUgYXZlYyB1biBkZSBtZXMgYW5jaWVucwpkb2NzLi4uIH5+Tm8gY29tbWVudHN+fi4KW140XTogSmUgbWUgc3VpcyByZW5kdSBjb21wdGUgcXUnaWwgZXN0IGxvbmcgcXVhbmQgamUgbCdhaSBmaW5pLgpbXjZdOiBDJ2VzdCB2cmFpbWVudCBoeXBlciBzaW1wbGUgZGUgbW9kaWZpZXIgbGUgZm9ybWF0IGRlIHNvcnRpZSB3b3JkClteN106IEplIHZvdXMgcHLDqXNlbnRlIGRlcyBleGN1c2VzIHNpIGlsIHkgYSBxdWVscXVlcyBhY2NlbnRzIHF1aSBtYW5xdWVudCBkYW5zIG1vbiB0ZXh0ZSwKZMO7IMOgIGwndXRpbGlzYXRpb24gYWJ1c2l2ZSBkJ3VuIGNsYXZpZXIgYW5nbGFpcy4K